/*
 * Matt Adams
 * TCSS 558 HW2
 * Fall 2013
 */
package rmi;

import java.io.IOException;
import java.rmi.AccessException;
import java.rmi.AlreadyBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import tools.CheckArgument;
import tools.Log;

/**
 * RMI Spelling Server.
 * 
 * @author Matt Adams
 */
public class RMISpellingServer {

    private final String serviceName;
    private final String fileName;
    private final int port;
    private RemoteSpellingObject remoteObject;
    
    /**
     * Constructs RMISpellingServer object.
     * 
     * @param portNameFileArray Listing of port, service name, and filename.
     */
    public RMISpellingServer(final String[] portNameFileArray) {
        this.port = CheckArgument.isValidPort(portNameFileArray[0]);
        this.serviceName = portNameFileArray[1];
        this.fileName = portNameFileArray[2];
    }
    
    /**
     * Starts rmi spelling server.
     */
    public void start() {
        try {
            this.remoteObject = new RemoteSpellingObject(this.fileName);
            final Remote remote = UnicastRemoteObject.exportObject(this.remoteObject, 0);
            Registry registry = getRegistry();
            registry.bind(serviceName, remote);
            Log.out("Exported spelling service as " + this.serviceName + " on registry port " + this.port);
        } catch (AccessException e) {
            Log.err("Access registry exception: " + e);
        } catch (RemoteException e) {
            Log.err("Problem exporting the spelling service: " + e);
        } catch (IOException e) {
            Log.err("Problem loading word list: " + e);
        } catch (AlreadyBoundException e) {
            Log.err("Service already bound: " + e);
        }
    }
    
    /**
     * Gets rmi registry from a host and port.
     * @return Returns rmi registry.
     */
    private Registry getRegistry() {
        Registry registry = null;
        try {
            registry = LocateRegistry.createRegistry(this.port);
        } catch (RemoteException e) {
            Log.err("Error creating registry at <port>: <" + this.port + ">: " + e);
        }
        return registry;
    }
    
    /**
     * Main to run server.
     * @param portNameFileArray Listing of port, service name, and filename.
     */
    public static void main(final String[] portNameFileArray) {
        if (portNameFileArray.length != 3) {
            Log.err("Usage of RMISpellingServer: <port> <service name> <word list filename>");
        } else {
            final RMISpellingServer rmiServer = new RMISpellingServer(portNameFileArray);
            rmiServer.start();
        }
    }
}
